package com.sxu.shadowdrawable;

import ohos.agp.components.Component;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.render.*;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.agp.utils.RectFloat;

public class ShadowDrawable extends ShapeElement {
	private Paint mShadowPaint;
	private Paint mBgPaint;
	private int mShadowRadius;
	private int mShape;
	private int mShapeRadius;
	private int mOffsetX;
	private int mOffsetY;
	private int mBgColor[];
	private RectFloat mRect;

	public final static int SHAPE_ROUND = 1;
	public final static int SHAPE_CIRCLE = 2;

	private ShadowDrawable(int shape, int[] bgColor, int shapeRadius, int shadowColor, int shadowRadius, int offsetX, int offsetY) {
		this.mShape = shape;
		this.mBgColor = bgColor;
		this.mShapeRadius = shapeRadius;
		this.mShadowRadius = shadowRadius;
		this.mOffsetX = offsetX;
		this.mOffsetY = offsetY;

		mShadowPaint = new Paint();
		mShadowPaint.setColor(new Color(shadowColor));
		mShadowPaint.setAntiAlias(true);
		mShadowPaint.setMaskFilter(new MaskFilter(shadowRadius, MaskFilter.Blur.NORMAL));
		mShadowPaint.setBlurDrawLooper(new BlurDrawLooper(shadowRadius, mOffsetX, mOffsetY, new Color(shadowColor)));
		//mShadowPaint.setShadowLayer(shadowRadius, offsetX, offsetY, shadowColor);
		//mShadowPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));

		mBgPaint = new Paint();
		mBgPaint.setAntiAlias(true);
	}

	@Override
	public void setBounds(int left, int top, int right, int bottom) {
		super.setBounds(left, top, right, bottom);
		mRect = new RectFloat(left + mShadowRadius - mOffsetX, top + mShadowRadius - mOffsetY, right - mShadowRadius - mOffsetX,
				bottom - mShadowRadius - mOffsetY);
	}

	private void onDraw(Canvas canvas){
		if (mBgColor != null) {
			if (mBgColor.length == 1) {
				Color color = new Color(mBgColor[0]);
				mBgPaint.setColor(color);
			} else {
				Color[] bgColors = new Color[mBgColor.length];
				for (int i = 0; i < mBgColor.length; i++) {
					Color color1 = new Color(mBgColor[i]);
					bgColors[i] = color1;
				}

				// 重点在这里
				Point[] pointArrays = new Point[]{new Point(mRect.left, mRect.getHeight() / 2), new Point(mRect.right, mRect.getHeight() / 2)};
				LinearShader shader = new LinearShader(pointArrays, new float[]{mRect.right, mRect.getHeight() / 2}, bgColors, Shader.TileMode.CLAMP_TILEMODE);
				mBgPaint.setShader(shader, Paint.ShaderType.LINEAR_SHADER);
			}
		}

		if (mShape == SHAPE_ROUND) {
			canvas.drawRoundRect(mRect, mShapeRadius, mShapeRadius, mShadowPaint);
			canvas.drawRoundRect(mRect, mShapeRadius, mShapeRadius, mBgPaint);
		} else {
			canvas.drawCircle(mRect.getHorizontalCenter(), mRect.getVerticalCenter(), Math.min(mRect.getWidth(), mRect.getHeight())/ 2, mShadowPaint);
			canvas.drawCircle(mRect.getHorizontalCenter(), mRect.getVerticalCenter(), Math.min(mRect.getWidth(), mRect.getHeight())/ 2, mBgPaint);
		}
	}

	@Override
	public void drawToCanvas(Canvas canvas) {
		super.drawToCanvas(canvas);
		onDraw(canvas);
	}

	@Override
	public void setAlpha(int alpha) {
		mShadowPaint.setAlpha(alpha);
	}

	public void setColorFilter(ColorFilter colorFilter) {
		mShadowPaint.setColorFilter(colorFilter);
	}

	public int getOpacity() {
		return 0;
		//return PixelFormat.TRANSLUCENT;
	}

	public static void setShadowDrawable(Component view, Element drawable) {
		view.setBackground(drawable);
		//view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
		//ViewCompat.setBackground(view, drawable);
	}

	/**
	 * 为指定View添加阴影
	 * @param view 目标View
	 * @param shapeRadius View的圆角
	 * @param shadowColor 阴影的颜色
	 * @param shadowRadius 阴影的宽度
	 * @param offsetX 阴影水平方向的偏移量
	 * @param offsetY 阴影垂直方向的偏移量
	 */
	public static void setShadowDrawable(Component view, int shapeRadius, int shadowColor, int shadowRadius, int offsetX, int offsetY) {
		ShadowDrawable drawable = new Builder()
				.setShapeRadius(shapeRadius)
				.setShadowColor(shadowColor)
				.setShadowRadius(shadowRadius)
				.setOffsetX(offsetX)
				.setOffsetY(offsetY)
				.builder();
		view.addDrawTask(new Component.DrawTask() {
			@Override
			public void onDraw(Component component, Canvas canvas) {
				drawable.setBounds(0, 0, component.getWidth(), component.getHeight());
				drawable.drawToCanvas(canvas);
			}
		}, Component.DrawTask.BETWEEN_BACKGROUND_AND_CONTENT);
		view.setBackground(drawable);
	}

	/**
	 * 为指定View设置带阴影的背景
	 * @param view 目标View
	 * @param bgColor View背景色
	 * @param shapeRadius View的圆角
	 * @param shadowColor 阴影的颜色
	 * @param shadowRadius 阴影的宽度
	 * @param offsetX 阴影水平方向的偏移量
	 * @param offsetY 阴影垂直方向的偏移量
	 */
	public static void setShadowDrawable(Component view, int bgColor, int shapeRadius, int shadowColor, int shadowRadius, int offsetX, int offsetY) {
		ShadowDrawable drawable = new Builder()
				.setBgColor(bgColor)
				.setShapeRadius(shapeRadius)
				.setShadowColor(shadowColor)
				.setShadowRadius(shadowRadius)
				.setOffsetX(offsetX)
				.setOffsetY(offsetY)
				.builder();
		view.addDrawTask(new Component.DrawTask() {
			@Override
			public void onDraw(Component component, Canvas canvas) {
				drawable.setBounds(0, 0, component.getWidth(), component.getHeight());
				drawable.drawToCanvas(canvas);
			}
		}, Component.DrawTask.BETWEEN_BACKGROUND_AND_CONTENT);
		view.setBackground(drawable);
	}

	/**
	 * 为指定View设置指定形状并带阴影的背景
	 * @param view 目标View
	 * @param shape View的形状 取值可为：GradientDrawable.RECTANGLE， GradientDrawable.OVAL， GradientDrawable.RING
	 * @param bgColor View背景色
	 * @param shapeRadius View的圆角
	 * @param shadowColor 阴影的颜色
	 * @param shadowRadius 阴影的宽度
	 * @param offsetX 阴影水平方向的偏移量
	 * @param offsetY 阴影垂直方向的偏移量
	 */
	public static void setShadowDrawable(Component view, int shape, int bgColor, int shapeRadius, int shadowColor, int shadowRadius, int offsetX, int offsetY) {
		ShadowDrawable drawable = new Builder()
				.setShape(shape)
				.setBgColor(bgColor)
				.setShapeRadius(shapeRadius)
				.setShadowColor(shadowColor)
				.setShadowRadius(shadowRadius)
				.setOffsetX(offsetX)
				.setOffsetY(offsetY)
				.builder();
		view.addDrawTask(new Component.DrawTask() {
			@Override
			public void onDraw(Component component, Canvas canvas) {
				drawable.setBounds(0, 0, component.getWidth(), component.getHeight());
				drawable.drawToCanvas(canvas);
			}
		}, Component.DrawTask.BETWEEN_BACKGROUND_AND_CONTENT);
		view.setBackground(drawable);
	}

	/**
	 * 为指定View设置带阴影的渐变背景
	 * @param view view
	 * @param bgColor bgColor
	 * @param shapeRadius shapeRadius
	 * @param shadowColor shadowColor
	 * @param shadowRadius shadowRadius
	 * @param offsetX offsetX
	 * @param offsetY offsetY
	 */
	public static void setShadowDrawable(Component view, int[] bgColor, int shapeRadius, int shadowColor, int shadowRadius, int offsetX, int offsetY) {
		ShadowDrawable drawable = new Builder()
				.setBgColor(bgColor)
				.setShapeRadius(shapeRadius)
				.setShadowColor(shadowColor)
				.setShadowRadius(shadowRadius)
				.setOffsetX(offsetX)
				.setOffsetY(offsetY)
				.builder();
		view.addDrawTask(new Component.DrawTask() {
			@Override
			public void onDraw(Component component, Canvas canvas) {
				drawable.setBounds(0, 0, component.getWidth(), component.getHeight());
				drawable.drawToCanvas(canvas);
			}
		}, Component.DrawTask.BETWEEN_BACKGROUND_AND_CONTENT);
		view.setBackground(drawable);
	}

	public static class Builder {
		private int mShape;
		private int mShapeRadius;
		private int mShadowColor;
		private int mShadowRadius;
		private int mOffsetX;
		private int mOffsetY;
		private int[] mBgColor;

		public Builder() {
			mShape = ShadowDrawable.SHAPE_ROUND;
			mShapeRadius = 0;
			mShadowColor = Color.getIntColor("#4d000000");
			mShadowRadius = 18;
			mOffsetX = 0;
			mOffsetY = 0;
			mBgColor = new int[1];
			mBgColor[0] = Color.TRANSPARENT.getValue();
		}

		public Builder setShape(int mhape) {
			this.mShape = mhape;
			return this;
		}

		public Builder setShapeRadius(int ShapeRadius) {
			this.mShapeRadius = ShapeRadius;
			return this;
		}

		public Builder setShadowColor(int shadowColor) {
			this.mShadowColor = shadowColor;
			return this;
		}

		public Builder setShadowRadius(int shadowRadius) {
			this.mShadowRadius = shadowRadius;
			return this;
		}

		public Builder setOffsetX(int OffsetX) {
			this.mOffsetX = OffsetX;
			return this;
		}

		public Builder setOffsetY(int OffsetY) {
			this.mOffsetY = OffsetY;
			return this;
		}

		public Builder setBgColor(int BgColor) {
			this.mBgColor[0] = BgColor;
			return this;
		}

		public Builder setBgColor(int[] BgColor) {
			this.mBgColor = BgColor.clone();
			return this;
		}

		public ShadowDrawable builder() {
			return new ShadowDrawable(mShape, mBgColor, mShapeRadius, mShadowColor, mShadowRadius, mOffsetX, mOffsetY);
		}
	}
}